<?php
	define('PASTE_TEMPLATE_VARIABLE_PREFIX', '{$');
	define('PASTE_TEMPLATE_VARIABLE_SUFFIX', '}');
	define('PASTE_TEMPLATE_FUNCTION_START_PREFIX', '<!--@');
	define('PASTE_TEMPLATE_FUNCTION_START_SUFFIX', '-->');
	define('PASTE_TEMPLATE_FUNCTION_END_PREFIX', '<!--');
	define('PASTE_TEMPLATE_FUNCTION_END_SUFFIX', '@-->');
	class templateParser {
		
		var $Buffer = '';
		var $Data = '';
		var $VariableData = array();
		var $FunctionData = array();
		var $replaceOffset = 0;
		
		function templateParser($template, $data) {
			$this->Buffer = $template->Buffer;
			$this->Data = $data;
			$this->_parseLoop();
		}
		
		function _parseLoop() {
			$split = str_split($this->Buffer);
			$seeking = null;
			$tmpBuffer = '';
			$tmpBufferStartOffset = null;
			$tmpBufferEndOffset = null;
			for($i=0;$i<count($split);$i++) {
				if($seeking == null) {
					if($this->cmpToOffset(PASTE_TEMPLATE_VARIABLE_PREFIX, ($i+1), $split)) {
						$seeking = PASTE_TEMPLATE_VARIABLE_SUFFIX;
						$tmpBufferStartOffset = $i+1;
					} elseif($this->cmpToOffset(PASTE_TEMPLATE_FUNCTION_START_PREFIX, ($i+1), $split)) {
						$seeking = PASTE_TEMPLATE_FUNCTION_END_SUFFIX;
						$tmpBufferStartOffset = $i+1;
					}
				} else if($this->cmpFromOffset($seeking, $i, $split)) {
					if($seeking == PASTE_TEMPLATE_VARIABLE_SUFFIX) {
						$tmpBufferEndOffset = $i-1;
						$this->VariableData[] = array("ORIGINAL" => $tmpBuffer);
					} else {
						$tmpBufferEndOffset = $i-1;
						$this->FunctionData[] = array("ORIGINAL" => $tmpBuffer);
					}
					$tmpBuffer = null;
					$seeking = null;
				} else {
					$tmpBuffer .= $split[$i];	
				}
			}
			foreach($this->FunctionData as $index => $functionRow) {
				$break = explode(PASTE_TEMPLATE_FUNCTION_START_SUFFIX, $functionRow['ORIGINAL']);
				$functionLine = $break[0];
				$break = explode(PASTE_TEMPLATE_FUNCTION_END_PREFIX, $break[1]);
				$functionCont = $break[0];
				
				$tok = explode(" ", $functionLine);
				$function = $tok[0];
				if($function == 'foreach') {
					$arrayVar = str_replace('$', '', $tok[1]);
					if(isset($this->Data[$arrayVar])) {
						$array = $this->Data[$arrayVar];
						$result = '';
						foreach($array as $row) {
							$html = str_replace($tok[3]."[URL]", $row['URL'], $functionCont);
							$html = str_replace($tok[3]."[ALT]", $row['ALT'], $html);
							$html = str_replace($tok[3]."[TEXT]", $row['TEXT'], $html);
							$result .= $html;
						}
						$this->FunctionData[$index]['RESULT'] = $result;
					} else {
						$this->FunctionData[$index]['RESULT'] = 'Unknown foreach array requested ('.$arrayVar.')';	
					}
				}
				$this->Buffer = str_replace(PASTE_TEMPLATE_FUNCTION_START_PREFIX.$this->FunctionData[$index]['ORIGINAL'].PASTE_TEMPLATE_FUNCTION_END_SUFFIX, $this->FunctionData[$index]['RESULT'], $this->Buffer);
			}
			
			foreach($this->VariableData as $index => $variableRow) {
				if(isset($this->Data[$variableRow['ORIGINAL']])) {
					$this->Buffer = str_replace(PASTE_TEMPLATE_VARIABLE_PREFIX.$variableRow['ORIGINAL'].PASTE_TEMPLATE_VARIABLE_SUFFIX, $this->Data[$variableRow['ORIGINAL']], $this->Buffer);
				} else {
					$this->Buffer = str_replace(PASTE_TEMPLATE_VARIABLE_PREFIX.$variableRow['ORIGINAL'].PASTE_TEMPLATE_VARIABLE_SUFFIX, "", $this->Buffer);				
				}
			}
		}
		
		function cmpToOffset($word, $offset, $buff) {
			$wordLength = strlen($word);
			if($wordLength == 1) return ($word == $buff[$offset]) ? true : false;
			$start = $offset - $wordLength;
			$output = '';
			try {
				for($i=$start;$i<$offset;$i++) {
					$output .= isset($buff[$i]) ? $buff[$i] : null;	
				}
			} catch(exception $e) {}
			if($output == $word) {
				return true;
			}
			return false;
		}
		function cmpFromOffset($word, $offset, $buff) {
			$wordLength = strlen($word);
			if($wordLength == 1) return ($word == $buff[$offset]) ? true : false;
			$end = $offset + $wordLength;
			$output = '';
			try {
				for($i=$offset;$i<$end;$i++) {
					$output .= $buff[$i];	
				}
			} catch(exception $e) {}
			if($output == $word) {
				return true;
			}
			return false;
		}
		function replaceBuffer($start, $end, $replacement) {
			$preBuffer = '';
			$postBuffer = '';
			$split = str_split($this->Buffer);
			for($i=0;$i<count($split);$i++) {
				if($i<$start) {
					$preBuffer .= $split[$i];
				} else if($i>$end) {
					$postBuffer .= $split[$i];	
				}
			}
			$this->Buffer = $preBuffer . $replacement . $postBuffer;
			$this->replaceOffset = strlen($replacement) - ($end - $start)  ;
		}
	}
?>